package branches.peter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import  org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class mainClass {

	
	public static void main(String[] args) throws IOException {
	
		if (args.length !=2){
			System.out.println("Syntax: webpage-and-figures-downloader url outputFolder");
			System.exit(1);
		}
		String urlString = args[0];
		String outputFolder = args[1];
		
		try{
			downloadURL(urlString,outputFolder);
			downloadFigures(urlString, outputFolder);
			
			//downloadURL("http://www.b2p.academy","C:/Test");
			//downloadURL("http://www.asp.net/web-pages", "C:/Test");
		}
		catch (IOException e)
		{
		
		}

		File directoryToZip = new File(outputFolder);

		List<File> fileList = new ArrayList<File>();
		System.out.println("---Getting references to all files in: " + directoryToZip.getCanonicalPath());
		getAllFiles(directoryToZip, fileList);
		System.out.println("---Creating zip file");
		writeZipFile(directoryToZip, fileList);
		System.out.println("---Done");
		
	}
	
	public static void downloadURL (String urlString, String outputFolder) throws IOException{
		
		URL u = new URL(urlString);
		String urlPath = u.getPath();
		String lastPathPart = FilenameUtils.getName(urlPath);
		String fileName=null;
		
		if (urlPath.isEmpty() || !lastPathPart.contains(".")){
			fileName = "index.html";
		}
		else{
			fileName = lastPathPart;
		}
		String filePathAndFileName = FilenameUtils.concat(outputFolder,fileName);
		System.out.println(filePathAndFileName);
		File f = new File( filePathAndFileName);
		FileUtils.copyURLToFile(u, f);
		
	}
	
	public static void downloadFigures(String urlString, String outputFolder) throws IOException{
		String figureUrl;
		Document doc = Jsoup.connect(urlString).get();
		Elements media = doc.select("[src]");
		for (Element src : media) {
            if (src.tagName().equals("img")){
            	figureUrl = src.attr("abs:src");
            	downloadURL(figureUrl,outputFolder);
            }
		}
	}
	

	public static void getAllFiles(File dir, List<File> fileList) {
		try {
			File[] files = dir.listFiles();
			for (File file : files) {
				fileList.add(file);
				if (file.isDirectory()) {
					System.out.println("directory:" + file.getCanonicalPath());
					getAllFiles(file, fileList);
				} else {
					System.out.println("     file:" + file.getCanonicalPath());
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void writeZipFile(File directoryToZip, List<File> fileList) {

		try {
			FileOutputStream fos = new FileOutputStream(directoryToZip.getName() + ".zip");
			ZipOutputStream zos = new ZipOutputStream(fos);

			for (File file : fileList) {
				if (!file.isDirectory()) { // we only zip files, not directories
					addToZip(directoryToZip, file, zos);
				}
			}

			zos.close();
			fos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void addToZip(File directoryToZip, File file, ZipOutputStream zos) throws FileNotFoundException,
			IOException {
		
		FileInputStream fis = new FileInputStream(file);

		// we want the zipEntry's path to be a relative path that is relative
		// to the directory being zipped, so chop off the rest of the path
		String zipFilePath = file.getCanonicalPath().substring(directoryToZip.getCanonicalPath().length() + 1,
				file.getCanonicalPath().length());
		System.out.println("Writing '" + zipFilePath + "' to zip file");
		ZipEntry zipEntry = new ZipEntry(zipFilePath);
		zos.putNextEntry(zipEntry);

		byte[] bytes = new byte[1024];
		int length;
		while ((length = fis.read(bytes)) >= 0) {
			zos.write(bytes, 0, length);
		}

		zos.closeEntry();
		fis.close();
	}

	
	

}
